<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
  <head>
    <title>Introduction - A very simple server</title>
    <!--  -->
  </head>

  <BODY text = "#000000"
    link="#000fff"
    vlink="#ff0f0f"
    bgcolor="#ffffff">

    <h3>Introduction - A very simple server</h3>

    <P>Now that we know how to implement a
      <A HREF="../Client/index.html">simple client</A>, we need to
      implement a server to test it out.
      We have to provide implementations for both the <CODE>Stock</CODE>
      and <CODE>Stock_Factory</CODE> interfaces,
      and then create an executable that incorporates those implementations.
    </P>

    <H3>Implementing the <CODE>Stock</CODE> interface</H3>

    <P>To keep things simple, let's implement a <CODE>Stock</CODE>
      object with a fixed price.  The constructor will receive all the
      parameters:
    </P>
<PRE>
class Quoter_Stock_i : public POA_Quoter::Stock {
public:
  Quoter_Stock_i (const char *symbol,
                  const char *full_name,
                  CORBA::Double price);

private:
  std::string symbol_;
  std::string full_name_;
  CORBA::Double price_;
};
</PRE>
    <P>In a server, CORBA objects and functions are implemented and
      represented by programming language data and functions. These
      programming entities that implement and represent CORBA objects
      are called <I>servants</I>. <I>Object Adapters</I> link the world of
      CORBA objects to the world of programming language servants. They
      provide services for creation of CORBA objects and their object
      references and for dispatching requests to the appropriate
      servants.
    </P>
    <P>Notice the name of the base class.  TAO implements the CORBA 2.2
      specification, which includes the Portable Object Adapter (hence
      the POA prefix).  This new Object Adapter fixes many problems
      with the previous versions of the CORBA specification, where the
      so-called Basic Object Adapter was used.  Unfortunately, the
      specification was ambiguous and lead to incompatible (yet
      compliant) implementations.
      Code based on the POA, and conforming to the CORBA 2.2
      specification, is almost completely portable,
      the only incompatibilities arising from the names of the
      generated header files and and other minor things.
      Those problems can be easily wrapped in helper classes, and the
      file names can be controlled through IDL compiler options in
      most cases.
    </P>
    <P>A server application may contain multiple POA instances, but all
      server applications have at least one POA called the <I>RootPOA</I>.
    <P>We have to implement the operations and attributes:
    </P>
<PRE>
class Quoter_Stock_i : public POA_Quoter::Stock {
public:
  // some details omitted
  char *symbol ();
  char *full_name ();
  CORBA::Double price ();
};

// In the .cpp file:
char *
Quoter_Stock_i::symbol ()
{
  return CORBA::string_dup (this->symbol_.c_str ());
}
</PRE>
    <P>The other attributes and methods are similar, so we don't
      reproduce them here.
    </P>

    <H4>Memory management rules for arguments</H4>

    <P>It is important to copy the strings before returning them,
      because the ORB will use <CODE>CORBA::string_free</CODE> to release
      them. The rationale is that over the network, the string must be
      copied anyway, hence, the client must be responsible for releasing
      the received string.  When both client and servers are in the same
      address space the ORB can optimize the path and invoke the server
      operation directly, without marshaling or demarshaling.  If the
      client is going to work with both local and remote servers, it
      should always expect to own the string.  In consequence, the server
      implementation must always allocate a copy and return the copy,
      because the server-side must also work identically for local and
      remote clients.  The memory management rules in CORBA are a bit
      subtle, but there are some simple rules to follow:
      <UL>
        <LI>You must make a copy of the memory that you return.  The
          caller is going to release it.
        </LI>
        <LI>Conversely, you must release the memory returned to you.  The
        callee made a copy.
        </LI>
        <LI>You don't own the memory that you receive as input
        arguments,
        you can only use it for the duration of the call.
        You must make a copy if you want to hold a reference to it
        after you return.
        </LI>
      </UL>
      The complete memory management rules can be found in the Henning and
      Vinoski book or the CORBA specification.
    </P>

    <P>Typing all this code seems tedious.  Can't the IDL compiler
      help with this?  After all, it seems as if the method declarations
      are completely specified!  The answer is yes, TAO's IDL compiler
      can generate empty implementations that you can modify.  Simply
      use the <KBD>-GI</KBD> option:
<PRE>
$ $TAO_ROOT/TAO_IDL/tao_idl -GI Quoter.idl
</PRE>
      The empty implementations are generated in the
      <CODE>QuoterI.h</CODE> and <CODE>QuoterI.cpp</CODE> files.
      Be advised that the <CODE>-GI</CODE> option overwrites these files
      every time, so it is better to copy your implementation to
      another file.
    </P>

    <H3>The Stock Factory implementation</H3>

    <P>Our first implementation of the factory will serve only two
      stocks, "RHAT" and "MSFT":
    </P>
<PRE>
class Quoter_Stock_Factory_i : public POA_Quoter::Stock_Factory
{
public:
  Quoter_Stock_Factory ();

  Quoter::Stock_ptr get_stock (const char *symbol);

private:
  Quoter_Stock_i rhat_;
  Quoter_Stock_i msft_;
};
</PRE>

    <P>The implementation of the <CODE>get_stock()</CODE> method is
      simple, just compare the symbol name and return the appropriate
      object reference:
    </P>
<PRE>
Quoter::Stock_ptr
Quoter_Stock_Factory_i::get_stock (const char *symbol)
{
  if (strcmp (symbol, "RHAT") == 0) {
    return this->rhat_._this();
  } else if (strcmp (symbol, "MSFT") == 0) {
    return this->msft_._this ();
  }
  throw Quoter::Invalid_Stock_Symbol ();
}
</PRE>

    <P>So what is that <CODE>_this()</CODE> method?  In the POA mapping
      the client-side stubs and server-side skeletons are not related
      through inheritance.  You must either explicitly activate the
      servant (your implementation object) or use <CODE>_this()</CODE> to
      activate it with its default POA.  <CODE>_this()</CODE> creates and
      registers a CORBA object under the RootPOA, and returns the created
      object reference for the new object. We will discuss more about
      explicit and implicit activation later, but at this point it is
      important to remove any thoughts about converting pointers to
      servants to object references or vice-versa, it just does not
      work that way.
    </P>

    <H3>Implementing a CORBA server</H3>

    <P>Now that we have all the object implementations in place, we
      must create the server executable.  We start with the ORB
      initialization:
    </P>
<PRE>
int main (int argc, char* argv[])
{
  try {
    // First initialize the ORB, that will remove some arguments...
    CORBA::ORB_var orb =
      CORBA::ORB_init (argc, argv,
                       "" /* the ORB name, it can be anything! */);
</PRE>

    <P>On startup, the ORB starts the POA in the {<em>holding state</em>},
      where all requests received are not processed until the POA is
      activated.  Meanwhile the requests are stored to some
      implementation limit.  TAO sets this limit to 0, because queueing
      is a severe source of overhead and unpredictability in real-time
      systems.
    </P>
    <P>What does this means for us? Well, we have to activate the POA.
      The process is a bit tedious.  First we gain access to the
      RootPOA:
<PRE>
    CORBA::Object_var poa_object =
      orb->resolve_initial_references ("RootPOA");
    PortableServer::POA_var poa =
      PortableServer::POA::_narrow (poa_object.in ());
</PRE>
    <P><CODE>resolve_initial_references()</CODE> is used to bootstrap
      all kinds of services, like the Naming Service and the Trading
      Service, but it is also used to gain access to other ORB
      interfaces, such as the RootPOA, the Current objects, and the
      Policy Managers.
    </P>
    <P>Now that we have gained access to the Root POA, we must obtain
      its POA manager.  The POA managers provide interfaces to activate
      and deactivate one or more POAs:
    </P>
<PRE>
    PortableServer::POAManager_var poa_manager =
      poa->the_POAManager ();
</PRE>
    <P>and now we activate the POA:
    </P>
<PRE>
    poa_manager->activate ();
</PRE>

    <P>The shutdown process is similar to the client side, but now we
      must also remember to destroy the POA.  Putting all the code
      above together, we get:
    </P>
<PRE>
int main (int argc, char* argv[])
{
  try {
    // First initialize the ORB, that will remove some arguments...
    CORBA::ORB_var orb =
      CORBA::ORB_init (argc, argv,
                       "" /* the ORB name, it can be anything! */);
    CORBA::Object_var poa_object =
      orb->resolve_initial_references ("RootPOA");
    PortableServer::POA_var poa =
      PortableServer::POA::_narrow (poa_object.in ());
    PortableServer::POAManager_var poa_manager =
      poa->the_POAManager ();
    poa_manager->activate ();

    // The application code goes here!

    // Destroy the POA, waiting until the destruction terminates
    poa->destroy (1, 1);
    orb->destroy ();
  }
  catch (const CORBA::Exception &ex) {
    std::cerr << "CORBA exception raised!" << std::endl;
  }
  return 0;
}
</PRE>

    <P>Now we create an instance of our stock factory implementation
      and activate it using <CODE>_this()</CODE>
    </P>
<PRE>
    Quoter_Stock_Factory_i stock_factory_i;

    Quoter::Stock_Factory_var stock_factory =
      stock_factory_i._this ();
</PRE>
    <P>Next we convert the object reference into an IOR string, so it
      can be used by the client:
    </P>
<PRE>
    CORBA::String_var ior = orb->object_to_string (stock_factory.in ());
    std::cerr << ior.in () << std::endl;
</PRE>

    <P>There is only one final detail.  We must run the ORB event loop
      to start processing requests from the client:
    </P>
<PRE>
    orb->run ();
</PRE>

    <P>There are many details that we have left out from this server,
      such as how to terminate the event loop, how to perform servant
      memory management, orderly deactivation of servants, and the fact
      is that it is not very flexible, but we have covered a number
      of other things, and more importantly we can test the client
      now!
    </P>

    <H3>Exercise 1</H3>

    <P>Flesh out the implementation.  You don't have to do it from
      scratch, as we provide you with the following files:
      <A HREF="Stock_i.h">Stock_i.h</A>,
      <A HREF="Stock_i.cpp">Stock_i.cpp</A>,
      <A HREF="Stock_Factory_i.h">Stock_Factory_i.h</A>
      <A HREF="Stock_Factory_i.cpp">Stock_Factory_i.cpp</A>,
      <A HREF="../Quoter.idl">Quoter.idl</A>
      and the always useful
      <A HREF="Quoter_Simple_Server.mpc">MPC file</A>
    </P>

    <H4>Solution</H4>

    <P>Compare your solution with
      <A HREF="server.cpp">server.cpp</A>.
    </P>

    <H3>Testing</H3>

    <P>To test this application we need a
      <A HREF="../Client/index.html">client</A>.
      We just run both of them:
<PRE>
$ server > ior_file
$ client file://ior_file MSFT RHAT
</PRE>
      Also test invalid symbols!
    </P>

    <hr>
    <address><a href="mailto:coryan@cs.wustl.edu">Carlos O'Ryan</a></address>
<!-- Created: Sat Nov 27 15:47:01 CST 1999 -->
<!-- hhmts start -->
Last modified: Sun Apr  1 15:03:38 PDT 2001
<!-- hhmts end -->
  </body>
</html>
